home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / LColorPicker / LColorPicker.cp < prev    next >
Encoding:
Text File  |  1995-08-28  |  5.9 KB  |  246 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        LColorPicker.cp
  3.  
  4.     Contains:    Support for modeless and movable modal color pickers.
  5.     
  6.                 ColorPicker 2.0 encapsulated for easier usage in C++.
  7.                 -  it has some really cool features no one uses,
  8.                 probably because Apple made it very flexible and thereby
  9.                 complicated the interface immensely.
  10.                 
  11.     Version:    1.0a1
  12.     
  13.     Written by: Chris Thomas
  14.  
  15.     Copyright:    © 1995 Chris K. Thomas. All Rights Reserved.
  16.  
  17.     Change History (most recent first):
  18.                  8/27/95        ckt        Fix RGB typing bugs in ColorSync.
  19.                  8/26/95        ckt        Moved menu stuff to new
  20.                                      framework-specific subclasses.
  21.                  8/25/95        ckt        Created
  22.     
  23.     Dependencies:
  24.                 Requires C++ exceptions.
  25.                 Requires RTTI (CW/7 and later).
  26.                 Throws OSErrs.
  27.                 Subclass of LSharable if PowerPlant is available
  28.                 (see header)
  29.                 Doesn't require ColorSync or ColorPicker 2.0.
  30.                 Doesn't use ColorSync even if it is present, so that
  31.                     ColorPicker Mgr handles conversion to/from RGBColor.
  32.                 [ColorSync support is planned for 1.1]
  33.                 Can't throw from outside the main thread, because
  34.                     Metrowerks doesn't have their exceptions implementation
  35.                     together.
  36.                 
  37.                 Is a subclass of LSharable if used with PowerPlant.
  38.                 
  39.     Usage:
  40.             myColorPicker = new LColorPicker("\pTrue colors", object->itsColor,
  41.                                 true, false);
  42.             ...
  43.             WaitNextEvent(everyEvent, &wneEvent...)
  44.             
  45.             myColorPicker->HandleEvent(wneEvent);
  46.             
  47. */
  48.  
  49.  
  50. // ——————• Includes———————————————————————————————————————————————————————————————————————
  51. #include "LColorPicker.h"
  52.  
  53. // ——————• Static member vars—————————————————————————————————————————————————————————————
  54. ColorChangedUPP        LColorPicker::sColorChangeUpp;  // * for live color change detection
  55.  
  56. // ——————• Lifetime———————————————————————————————————————————————————————————————————————
  57. #pragma mark • Lifetime
  58.  
  59. LColorPicker::LColorPicker(StringPtr inPrompt, RGBColor& inOldColor,
  60.                             Boolean isMovable, Boolean isModal)
  61. {
  62.     Point frontAndCenter = {-1, -1};
  63.  
  64. //    mCurrentColor = inOldColor;
  65.     mPicker = NULL;
  66.     
  67.     OSErr    theErr;
  68.     long    gestaltValue;
  69.     
  70.     theErr = Gestalt(gestaltColorPickerVersion, &gestaltValue);
  71.     
  72.     // * one oh compatibility
  73.     if(theErr != noErr)    // * gestaltColorPickerVersion isn't installed previously
  74.     {
  75.         Boolean ok = ::GetColor(frontAndCenter, inPrompt, &inOldColor, &mCurrentColor);
  76.         
  77.         if(ok)
  78.         {
  79.             UserFinalizedColor();
  80.             UserSaysOK();
  81.         }
  82.         else
  83.         {
  84.             UserSaysCancel();
  85.         }
  86.         // * don't reference self afterwards,
  87.         //   because we might be deleted by a subclass ("delete this")
  88.         return;
  89.     }
  90.     
  91.     // * fill in the system dialog info for a 2.0 system-owned color picker dialog
  92.     SystemDialogInfo    ourInfo;
  93.     
  94.     if(isModal == true)
  95.         ourInfo.flags += DialogIsModal;
  96.     
  97.     if(isMovable)
  98.         ourInfo.flags += DialogIsMoveable;
  99.         
  100.     ourInfo.flags = CanModifyPalette + CanAnimatePalette + DialogIsMoveable;
  101.         
  102.     ourInfo.pickerType = 0L;
  103.     ourInfo.placeWhere = kDeepestColorScreen;
  104.     
  105.     GetMenuItems(ourInfo.mInfo);    // * get menu info from subclass
  106.     
  107.     // * create the picker
  108.     
  109.     theErr = CreateColorDialog(&ourInfo, &mPicker);
  110.     if(theErr != noErr)
  111.         throw theErr;
  112.         
  113.     // * set up the picker's variables
  114.     
  115.     SetPrompt(inPrompt);
  116.     SetColor(inOldColor, kOriginalColor);
  117.     SetColor(inOldColor, kNewColor);
  118.  
  119.     SetPickerVisibility(mPicker, true);
  120. }
  121.  
  122. LColorPicker::~LColorPicker()
  123. {
  124.     if(mPicker)
  125.         DisposeColorPicker(mPicker);
  126. }
  127.  
  128. // ——————• Events———————————————————————————————————————————————————————————————————
  129. #pragma mark • Events
  130.  
  131. // * returns true if the event is a picker event
  132. short LColorPicker::HandleEvent(EventRecord *inEvent)
  133. {
  134.     Boolean        outPickerEvent;
  135.     EventData    ourEventData;
  136.     
  137.     // * create UniversalProcPtrs if necessary
  138.     if(sColorChangeUpp == NULL)
  139.     {
  140.         sColorChangeUpp = NewColorChangedProc(ColorChangeProc);
  141.         
  142.         if(sColorChangeUpp == NULL)
  143.             throw 'sh*t';    // * boy are we in trouble
  144.                             //   if we can't alloc that
  145.     }
  146.     
  147.     ourEventData.event = inEvent;
  148.     ourEventData.colorProc = sColorChangeUpp;
  149.     ourEventData.colorProcData = (long) this;
  150.     
  151.     GrafPtr        savePort;
  152.     
  153.     GetPort(&mSavePort);
  154.     DoPickerEvent(mPicker, &ourEventData);
  155.     
  156.     if(ourEventData.handled)
  157.     {
  158.         switch(ourEventData.action)
  159.         {
  160.             case kColorChanged:
  161.                 UserFinalizedColor();
  162.                 break;
  163.             case kOkHit:
  164.                 UserSaysOK();
  165.                 break;
  166.             case kCancelHit:
  167.                 UserSaysCancel();
  168.                 break;
  169.             default:
  170.                 break;
  171.                 
  172.         }
  173.         
  174.         return ourEventData.action;
  175.     }
  176.     else
  177.         return kDidNothing;
  178.         
  179. /*
  180.     • The Color Picker Manager lies about handling events.
  181.     It changes the cursor, then tells us it didn't handle the event.
  182.     There's no easy way to fix this.
  183.         
  184.     • Also, why do we have to handle the edit menu if we already
  185.     told it the correct items and it knows it's own dialog item
  186.     numbers?
  187. */
  188. }
  189.  
  190. Boolean LColorPicker::CanClose()
  191. {
  192.     EventData    ourEvent;
  193.     
  194.     ourEvent.event = NULL;
  195.     ourEvent.forcast = kDialogAccept;
  196.     
  197.     DoPickerEvent(mPicker, &ourEvent);
  198.     return (!ourEvent.handled);
  199. }
  200.  
  201. // ——————• Accessors—————————————————————————————————————————————————shrubbery——————————
  202. #pragma mark • Accessors
  203.  
  204. void LColorPicker::SetColor(RGBColor &inColor, ColorType inType)
  205. {
  206.     if(inType == kNewColor)
  207.         mCurrentColor = inColor;
  208.     
  209.     PMColor ourColor;
  210.     
  211.     // * CMRGBColor is the same exact structure as QuickDraw RGBColor! Jeeeez...
  212.     CMRGBColor    *ourCMColor = reinterpret_cast< CMRGBColor *>(&inColor);
  213.     
  214.     ourColor.color.rgb = *ourCMColor;
  215.     ourColor.profile = NULL;
  216.     
  217.     SetPickerColor(mPicker, inType, &ourColor);
  218. }
  219.  
  220. void LColorPicker::GetColor(RGBColor &outColor)
  221. {
  222.     outColor = mCurrentColor;
  223. }
  224.  
  225. void LColorPicker::SetPrompt(const StringPtr inPrompt)
  226. {
  227.     SetPickerPrompt(mPicker, inPrompt);
  228. }
  229.  
  230. // ——————• Callbacks——————————————————————————————————————————————————————————————————
  231. #pragma mark • Callbacks
  232.  
  233. // * handle live color changes
  234. pascal void LColorPicker::ColorChangeProc(LColorPicker *inInstance, PMColor *inNewColor)
  235. {
  236.     inInstance->mCurrentColor = *reinterpret_cast<RGBColor *>(&inNewColor->color.rgb);
  237.     
  238.     GrafPtr    localSave;
  239.     
  240.     GetPort(&localSave);            // * save color picker’s port
  241.     SetPort(inInstance->mSavePort);    // * set port back to user’s port
  242.     
  243.     inInstance->UserChangingColor();
  244.     
  245.     SetPort(localSave);
  246. }